package com.boatAnchorAssistant.service.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.boatAnchorAssistant.pojo.dto.department.GetDepartmentListDto;
import com.boatAnchorAssistant.pojo.entity.Department;
import com.boatAnchorAssistant.pojo.entity.Tenant;
import com.boatAnchorAssistant.pojo.event.tenant.CreateTenantEvent;
import com.boatAnchorAssistant.pojo.event.tenant.DeleteTenantEvent;
import com.boatAnchorAssistant.pojo.event.tenant.EditTenantEvent;
import com.boatAnchorAssistant.pojo.param.tenant.*;
import com.boatAnchorAssistant.pojo.vo.tenant.*;
import com.boatAnchorAssistant.pojo.dto.tenant.*;
import com.boatAnchorAssistant.service.repository.in.DepartmentRepository;
import com.boatAnchorAssistant.service.repository.in.RoleRepository;
import com.boatAnchorAssistant.service.repository.in.TenantRepository;
import com.boatAnchorAssistant.service.repository.in.UserRepository;
import com.boatAnchorAssistant.service.service.in.TenantService;
import nirvana.core.domains.vo.PageResult;
import nirvana.core.exceptions.BizException;
import nirvana.core.utils.ids.IdGenerator;
import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;


import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 【描 述】：企业服务
 * 【环 境】：J2SE 17
 * 【详 细】：
 *
 */
@Service
public class TenantServiceImpl implements TenantService {

    private final TenantRepository tenantRepository;

    private final DepartmentRepository departmentRepository;

    private final UserRepository userRepository;

    private final RoleRepository roleRepository;

    private final ApplicationEventPublisher publisher;

    public TenantServiceImpl(TenantRepository tenantRepository, DepartmentRepository departmentRepository, UserRepository userRepository, RoleRepository roleRepository, ApplicationEventPublisher publisher) {
        this.tenantRepository = tenantRepository;
        this.departmentRepository = departmentRepository;
        this.userRepository = userRepository;
        this.roleRepository = roleRepository;
        this.publisher = publisher;
    }


    /**
     * 创建企业
     *
     * @param param
     */
    @Override
    public void createTenant(CreateTenantParam param) {
        Tenant tenant = new Tenant();
        BeanUtils.copyProperties(param, tenant);
        Long id = IdGenerator.SNOW.generate();
        tenant.setId(id);
        tenant.setIsDisable(!param.getEnabled());


        /**
         * 管理员id
         */
        Long adminUserId = IdGenerator.SNOW.generate();
        tenant.setAdminId(adminUserId);


        tenantRepository.create(tenant);


        /**
         * 发送创建企业的事件
         */
        CreateTenantEvent event = new CreateTenantEvent();
        BeanUtils.copyProperties(param, event);

        event.setTenantId(id);
        event.setTenantName(tenant.getName());

        //预置用户、角色、部门id
        event.setAdminUserId(adminUserId);
        event.setDepartmentId(IdGenerator.SNOW.generate());
        event.setAdminRoleId(IdGenerator.SNOW.generate());

        publisher.publishEvent(event);
    }

    /**
     * 修改企业
     *
     * @param param
     */
    @Override
    public void editTenant(EditTenantParam param) {
        Long id = param.getId();
        Tenant tenant = tenantRepository.getByIdCheck(id);

        BeanUtils.copyProperties(param, tenant);
        tenant.setIsDisable(!param.getEnabled());
        tenantRepository.edit(tenant);

        /**
         * 发送编辑企业事件
         */
        EditTenantEvent event = new EditTenantEvent();
        BeanUtils.copyProperties(param, event);
        event.setTenantId(id);
//        publisher.publishEvent(event);
    }

    /**
     * 移除企业
     *
     * @param id
     */
    @Override
    public void removeTenant(Long id) {
        tenantRepository.removeById(id);

        /**
         * 发送事件校验
         */

        //企业id
//        DeleteTenantEvent event =new DeleteTenantEvent();
//        event.setTenantId(id);
//
//        //部门id列表
//        List<Long> departmentIdList = departmentRepository.getIdListByTenantId(id);
//        event.setDepartmentIdList(departmentIdList);
//
//        Long topDepartmentId = departmentRepository.getTopDepartmentId(id);
//
//        //用户id列表
//        List<Long> userIdList = userRepository.getUserIdListByTenantId(id);
//        event.setUserIdList(userIdList);
//
//        //角色id列表
//        List<Long> roleIdList = roleRepository.getRoleIdListByTenantId(id);
//        event.setRoleIdList(roleIdList);
//
//
//
//        publisher.publishEvent(event);
    }

    /**
     * 启动/禁用企业
     *
     * @param id
     */
    @Override
    public void enabledTenant(Long id) {
        Tenant tenant = tenantRepository.getByIdCheck(id);
        tenant.setIsDisable(!tenant.getIsDisable());
        tenantRepository.edit(tenant);
    }

    /**
     * 获取企业详情
     *
     * @param id
     * @return
     */
    @Override
    public GetTenantVo getTenant(Long id) {
        Tenant tenant = tenantRepository.getByIdCheck(id);
        GetTenantVo vo = new GetTenantVo();
        BeanUtils.copyProperties(tenant, vo);
        vo.setEnabled(!tenant.getIsDisable());
        return vo;
    }

    /**
     * 获取企业 列表
     *
     * @param param
     * @return
     */
    @Override
    public PageResult<GetTenantListVo> getTenantList(GetTenantListParam param) {

        SelectTenantDto dto = new SelectTenantDto();
        BeanUtils.copyProperties(param, dto);
        Page<Tenant> page = tenantRepository.selectTenant(dto);
        List<Tenant> tenantList = page.getRecords();
        List<GetTenantListVo> list = new ArrayList<>();
        for (Tenant tenant : tenantList) {
            GetTenantListVo vo = new GetTenantListVo();
            BeanUtils.copyProperties(tenant, vo);

            list.add(vo);
        }
        return new PageResult<>(list, page);

    }

    /**
     * 获取企业下拉列表
     *
     * @param param
     * @return
     */
    @Override
    public List<GetTenantDownListVo> getTenantDownList(GetTenantDownListParam param) {
        Tenant po = new Tenant();
        if (param != null) {
            BeanUtils.copyProperties(param, po);
        }
        List<Tenant> tenantList = tenantRepository.getListByEntity(po);

        List<GetTenantDownListVo> list = new ArrayList<>();
        for (Tenant tenant : tenantList) {
            GetTenantDownListVo vo = new GetTenantDownListVo();
            BeanUtils.copyProperties(tenant, vo);
            list.add(vo);
        }
        return list;
    }

    /**
     * 部门树型
     *
     * @param param
     * @return
     */
    @Override
    public List<TenantTreeVo> getTenantTree(GetTenantTreeParam param) {
        GetDepartmentListDto dto = new GetDepartmentListDto();
        List<Department> departments = departmentRepository.getDepartmentListByDto(dto);

        List<TenantTreeVo> list = new ArrayList<>();

        for (Department department : departments) {
            TenantTreeVo vo = new TenantTreeVo();
            BeanUtils.copyProperties(department, vo);
            vo.setDepartmentId(department.getId());
            vo.setEnabled(!department.getIsDisable());
            vo.setLevel(department.getLevel());
            list.add(vo);
        }

        Map<Long, List<TenantTreeVo>> map = list.stream().collect(Collectors.groupingBy(TenantTreeVo::getParentId));


        for (TenantTreeVo vo : list) {
            Long id = vo.getDepartmentId();
            List<TenantTreeVo> child = map.get(id);
            if (CollectionUtils.isEmpty(child)) {
                child = Collections.EMPTY_LIST;
            }
            vo.setChild(child);
        }

        return map.get(0L);
    }


}



